package com.xdxc.utils;

import java.util.*;
import java.util.concurrent.*;
import java.util.function.Supplier;
import java.util.stream.Collectors;
public class CompletableFutureUtil {
    private static final Executor queryExecutor = Executors.newFixedThreadPool(
            Runtime.getRuntime().availableProcessors() * 2);

    public static <T> CompletableFuture<T> supplyAsync(Supplier<T> supplier) {
        if (supplier == null) {
            return CompletableFuture.completedFuture(null);
        }
        return CompletableFuture.supplyAsync(supplier, queryExecutor);
    }

    public static CompletableFuture<Map<String, Object>> allOf(Supplier<?>... suppliers) {
        // Handle null input
        if (suppliers == null) {
            return CompletableFuture.completedFuture(Collections.emptyMap());
        }

        // Create futures with proper error handling
        List<CompletableFuture<?>> futures = new ArrayList<>();
        for (int i = 0; i < suppliers.length; i++) {
            final int index = i;
            try {
                Supplier<?> supplier = suppliers[index];
                CompletableFuture<?> future = (supplier != null)
                        ? supplyAsync(supplier).exceptionally(e -> null)
                        : CompletableFuture.completedFuture(null);
                futures.add(future);
            } catch (Exception e) {
                futures.add(CompletableFuture.completedFuture(null));
            }
        }

        // Convert to array safely
        CompletableFuture<?>[] futureArray = futures.toArray(new CompletableFuture[0]);
        if (futureArray.length == 0) {
            return CompletableFuture.completedFuture(Collections.emptyMap());
        }

        return CompletableFuture.allOf(futureArray)
                .handle((v, ex) -> {
                    Map<String, Object> results = new ConcurrentHashMap<>();
                    for (int i = 0; i < futures.size(); i++) {
                        String key = "data" + i;
                        try {
                            Object value = futures.get(i).getNow(null); // Safe get without join
                            results.put(key, value);
                        } catch (Exception e) {
                            results.put(key, null);
                        }
                    }
                    return results;
                });
    }
}